<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        canvas{
            border: 1px solid #ccc;
        }
    </style>
</head>
<body>
    <canvas id="canvasWebgl" width="500" height="500"></canvas>

    <!--顶点着色器-->
    <script id="vertex-shader" type="x-shader/x-vertex">
        attribute vec4 aPosition;
        uniform mat4 u_x_matrix;
        uniform mat4 u_y_matrix;
        void main(){
            gl_Position = u_x_matrix*u_y_matrix*aPosition;
        }
    </script>
    <!--片元着色器-->
    <script id="fragment-shader" type="x-shader/x-fragment">
        precision mediump float;
        uniform vec4 uColor;
        void main(){
            gl_FragColor = uColor;
        }
    </script>
    <script>
        const gl = document.getElementById('canvasWebgl').getContext('webgl');
        // 创建顶点着色器和片元着色器
        const vertexShader = gl.createShader(gl.VERTEX_SHADER);
        const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
        // 获取着色器源码
        const vertexSource = document.getElementById('vertex-shader').innerText;
        const fragmentSource = document.getElementById("fragment-shader").innerText;
        // 绑定着色器源码
        gl.shaderSource(vertexShader, vertexSource);
        gl.shaderSource(fragmentShader, fragmentSource);
        // 编译着色器源码
        gl.compileShader(vertexShader);
        gl.compileShader(fragmentShader);
        // 创建程序对象
        const program = gl.createProgram();
        gl.attachShader(program, vertexShader);
        gl.attachShader(program, fragmentShader);
        gl.linkProgram(program);
        gl.useProgram(program);

        const vertex = new Float32Array([
          //前面
          -0.5, -0.5, 0.5,
          0.5, -0.5, 0.5,
          0.5, 0.5, 0.5,
          -0.5, 0.5, 0.5,
          // 后面
          -0.5, -0.5, -0.5,
          -0.5, 0.5, -0.5,
          0.5, 0.5, -0.5,
          0.5, -0.5, -0.5,
          //上面
          -0.5, 0.5, -0.5,
          -0.5, 0.5, 0.5,
          0.5, 0.5, 0.5,
          0.5, 0.5, -0.5,
          // 下面
          -0.5, -0.5, -0.5,
          0.5, -0.5, -0.5,
          0.5, -0.5, 0.5,
          -0.5, -0.5, 0.5,
          // 右面
          0.5, -0.5, -0.5,
          0.5, 0.5, -0.5,
          0.5, 0.5, 0.5,
          0.5, -0.5, 0.5,
          // 左面
          -0.5, -0.5, -0.5,
          -0.5, -0.5, 0.5,
          -0.5, 0.5, 0.5,
          -0.5, 0.5, -0.5,
        ])
        // 使用缓冲区绑定顶点数据
        const buffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
        gl.bufferData(gl.ARRAY_BUFFER, vertex, gl.STATIC_DRAW);

        // 三角形的顶点索引
        const indices = new Uint16Array([
          0,1,2,
          0,2,3,
          4,5,6,
          4,6,7,
          8,9,10,
          8,10,11,
          12,13,14,
          12,14,15,
          16,17,18,
          16,18,19,
          20,21,22,
          20,22,23,
        ])
        const indexBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
        gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);

        const positionLocation = gl.getAttribLocation(program, 'aPosition')
        gl.vertexAttribPointer(positionLocation, 3, gl.FLOAT, false, 3*Float32Array.BYTES_PER_ELEMENT, 0);
        gl.enableVertexAttribArray(positionLocation);

        // const faceColors = [
        //   [1.0, 0.0, 0.0, 1.0],
        //   [0.0, 1.0, 0.0, 1.0],
        //   [0.0, 0.0, 1.0, 1.0],
        //   [1.0, 1.0, 0.0, 1.0],
        //   [1.0, 0.0, 1.0, 1.0],
        //   [0.0, 1.0, 1.0, 1.0],
        // ]
        const faceColors = [
          [1.0, 0.0, 0.0, 1.0],
          [0.0, 1.0, 0.0, 1.0],
          [0.0, 0.0, 1.0, 1.0],
          [1.0, 1.0, 0.0, 1.0],
          [1.0, 0.0, 1.0, 1.0],
          [0.0, 1.0, 1.0, 1.0],
        ]
        const colorLocation = gl.getUniformLocation(program, 'uColor');
        // 激活深度比较，并更新深度缓冲区
        gl.enable(gl.DEPTH_TEST);
        const u_x_matrix = gl.getUniformLocation(program, 'u_x_matrix')
        const u_y_matrix = gl.getUniformLocation(program, 'u_y_matrix')
        let deg = 10
        /**
         *
         *  float radian = radians(10.0);
         *             float cos = cos(radian);
         *             float sin = sin(radian);
         *             mat4 mx = mat4(
         *                 1,0,0,0,
         *                 0,cos,-sin,0,
         *                 0,sin,cos,0,
         *                 0,0,0,1
         *             );
         *             mat4 my = mat4(
         *                 cos,0,-sin,0,
         *                 0,1,0,0,
         *                 sin,0,cos,0,
         *                 0,0,0,1
         *             );
         */
        function render() {
          deg += 0.2;
          let radian = deg * Math.PI/180;
          let cos = Math.cos(radian);
          let sin = Math.sin(radian);
          let mx = new Float32Array([
            1,0,0,0,
            0,cos,-sin,0,
            0,sin,cos,0,
            0,0,0,1
          ])
          let my = new Float32Array([
            cos,0,-sin,0,
            0,1,0,0,
            sin,0,cos,0,
            0,0,0,1
          ])
          gl.uniformMatrix4fv(u_x_matrix, false, mx);
          gl.uniformMatrix4fv(u_y_matrix, false, my);
          for (let i = 0; i < 6; i++) {
            gl.uniform4fv(colorLocation, faceColors[i]);
            gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, i*6*Uint16Array.BYTES_PER_ELEMENT)
          }
          requestAnimationFrame(render)
        }
        render()
    </script>
</body>
</html>